jetcrab\lexer\scanners/
operator.rs

1use crate::lexer::scanners::LexerCore;
2use crate::lexer::{LexerError, TokenKind};
3
4pub trait OperatorReader {
5    fn read_operator(&mut self) -> Result<TokenKind, LexerError>;
6}
7
8impl<T> OperatorReader for T
9where
10    T: LexerCore,
11{
12    fn read_operator(&mut self) -> Result<TokenKind, LexerError> {
13        let c = self.source()[self.pos()];
14
15        // Check for three-character operators first
16        if self.pos() + 2 < self.source().len() {
17            let next_c = self.source()[self.pos() + 1];
18            let next_next_c = self.source()[self.pos() + 2];
19            let three_char_op = format!("{}{}{}", c, next_c, next_next_c);
20
21            match three_char_op.as_str() {
22                "===" => {
23                    self.advance_pos();
24                    self.advance_pos();
25                    self.advance_pos();
26                    return Ok(TokenKind::StrictEqual);
27                }
28                "!==" => {
29                    self.advance_pos();
30                    self.advance_pos();
31                    self.advance_pos();
32                    return Ok(TokenKind::StrictNotEqual);
33                }
34                "..." => {
35                    self.advance_pos();
36                    self.advance_pos();
37                    self.advance_pos();
38                    return Ok(TokenKind::Spread);
39                }
40                _ => {}
41            }
42        }
43
44        // Check for two-character operators
45        if self.pos() + 1 < self.source().len() {
46            let next_c = self.source()[self.pos() + 1];
47            let two_char_op = format!("{}{}", c, next_c);
48
49            match two_char_op.as_str() {
50                "==" => {
51                    self.advance_pos();
52                    self.advance_pos();
53                    return Ok(TokenKind::Equal);
54                }
55                "!=" => {
56                    self.advance_pos();
57                    self.advance_pos();
58                    return Ok(TokenKind::NotEqual);
59                }
60                "<=" => {
61                    self.advance_pos();
62                    self.advance_pos();
63                    return Ok(TokenKind::LessThanEqual);
64                }
65                ">=" => {
66                    self.advance_pos();
67                    self.advance_pos();
68                    return Ok(TokenKind::GreaterThanEqual);
69                }
70                "++" => {
71                    self.advance_pos();
72                    self.advance_pos();
73                    return Ok(TokenKind::Increment);
74                }
75                "--" => {
76                    self.advance_pos();
77                    self.advance_pos();
78                    return Ok(TokenKind::Decrement);
79                }
80                "&&" => {
81                    self.advance_pos();
82                    self.advance_pos();
83                    return Ok(TokenKind::LogicalAnd);
84                }
85                "||" => {
86                    self.advance_pos();
87                    self.advance_pos();
88                    return Ok(TokenKind::LogicalOr);
89                }
90                "**" => {
91                    self.advance_pos();
92                    self.advance_pos();
93                    return Ok(TokenKind::StarStar);
94                }
95                "=>" => {
96                    self.advance_pos();
97                    self.advance_pos();
98                    return Ok(TokenKind::Arrow);
99                }
100                "??" => {
101                    self.advance_pos();
102                    self.advance_pos();
103                    return Ok(TokenKind::NullishCoalescing);
104                }
105                "+=" => {
106                    self.advance_pos();
107                    self.advance_pos();
108                    return Ok(TokenKind::PlusAssign);
109                }
110                "-=" => {
111                    self.advance_pos();
112                    self.advance_pos();
113                    return Ok(TokenKind::MinusAssign);
114                }
115                "*=" => {
116                    self.advance_pos();
117                    self.advance_pos();
118                    return Ok(TokenKind::StarAssign);
119                }
120                "/=" => {
121                    self.advance_pos();
122                    self.advance_pos();
123                    return Ok(TokenKind::SlashAssign);
124                }
125                "%=" => {
126                    self.advance_pos();
127                    self.advance_pos();
128                    return Ok(TokenKind::PercentAssign);
129                }
130                "**=" => {
131                    self.advance_pos();
132                    self.advance_pos();
133                    self.advance_pos();
134                    return Ok(TokenKind::StarStarAssign);
135                }
136                "<<=" => {
137                    self.advance_pos();
138                    self.advance_pos();
139                    self.advance_pos();
140                    return Ok(TokenKind::LeftShiftAssign);
141                }
142                ">>=" => {
143                    self.advance_pos();
144                    self.advance_pos();
145                    self.advance_pos();
146                    return Ok(TokenKind::RightShiftAssign);
147                }
148                ">>>=" => {
149                    self.advance_pos();
150                    self.advance_pos();
151                    self.advance_pos();
152                    self.advance_pos();
153                    return Ok(TokenKind::UnsignedRightShiftAssign);
154                }
155                "&=" => {
156                    self.advance_pos();
157                    self.advance_pos();
158                    return Ok(TokenKind::BitwiseAndAssign);
159                }
160                "|=" => {
161                    self.advance_pos();
162                    self.advance_pos();
163                    return Ok(TokenKind::BitwiseOrAssign);
164                }
165                "^=" => {
166                    self.advance_pos();
167                    self.advance_pos();
168                    return Ok(TokenKind::BitwiseXorAssign);
169                }
170                _ => {}
171            }
172        }
173
174        // Single character operators
175        match c {
176            '(' => {
177                self.advance_pos();
178                Ok(TokenKind::LeftParen)
179            }
180            ')' => {
181                self.advance_pos();
182                Ok(TokenKind::RightParen)
183            }
184            '{' => {
185                self.advance_pos();
186                Ok(TokenKind::LeftBrace)
187            }
188            '}' => {
189                self.advance_pos();
190                Ok(TokenKind::RightBrace)
191            }
192            '[' => {
193                self.advance_pos();
194                Ok(TokenKind::LeftBracket)
195            }
196            ']' => {
197                self.advance_pos();
198                Ok(TokenKind::RightBracket)
199            }
200            '.' => {
201                self.advance_pos();
202                Ok(TokenKind::Dot)
203            }
204            ';' => {
205                self.advance_pos();
206                Ok(TokenKind::Semicolon)
207            }
208            ',' => {
209                self.advance_pos();
210                Ok(TokenKind::Comma)
211            }
212            ':' => {
213                self.advance_pos();
214                Ok(TokenKind::Colon)
215            }
216            '?' => {
217                self.advance_pos();
218                Ok(TokenKind::Question)
219            }
220            '!' => {
221                self.advance_pos();
222                Ok(TokenKind::Exclamation)
223            }
224            '~' => {
225                self.advance_pos();
226                Ok(TokenKind::Tilde)
227            }
228            '=' => {
229                self.advance_pos();
230                Ok(TokenKind::Assign)
231            }
232            '+' => {
233                self.advance_pos();
234                Ok(TokenKind::Plus)
235            }
236            '-' => {
237                self.advance_pos();
238                Ok(TokenKind::Minus)
239            }
240            '*' => {
241                self.advance_pos();
242                Ok(TokenKind::Star)
243            }
244            '/' => {
245                self.advance_pos();
246                Ok(TokenKind::Slash)
247            }
248            '%' => {
249                self.advance_pos();
250                Ok(TokenKind::Percent)
251            }
252            '<' => {
253                self.advance_pos();
254                Ok(TokenKind::LessThan)
255            }
256            '>' => {
257                self.advance_pos();
258                Ok(TokenKind::GreaterThan)
259            }
260            '&' => {
261                self.advance_pos();
262                Ok(TokenKind::BitwiseAnd)
263            }
264            '|' => {
265                self.advance_pos();
266                Ok(TokenKind::BitwiseOr)
267            }
268            '^' => {
269                self.advance_pos();
270                Ok(TokenKind::BitwiseXor)
271            }
272            _ => Err(LexerError::UnexpectedCharacter(c)),
273        }
274    }
275}